import copy
from datetime import datetime, timedelta


class DataProcess():
    DATA_MAP = {
        "0001": {
            1: 1200,
            2: 2400,
            3: 4800,
            4: 9600,
            5: 19200,
            6: 38400,
            7: 57600,
            8: 115200
        },
        "000E": {
            52343: "False",
            0: "True",
        },

        "000F": {
            0: "正常模式",
            1: "仓储模式",
        },
        "001A": {
            0: "正常",
            1: "低压",
        },
        # "0057": {
        #     1: "打开",
        #     0: "关闭",
        # },
        "0020": {
            0: "关闭",
            1: "上午开启",
            2: "下午开启",
        },
        "010B": {
            0: "正常",
            1: "预警",
        },
        "010C": {
            0: "正常",
            1: "报警",
        },
        "010E": {
            0: "正常",
            1: "预警",
        },
        "010F": {
            0: "正常",
            1: "报警",
        },
        "0111": {
            0: "正常",
            1: "预警",
        },
        "0112": {
            0: "正常",
            1: "报警",
        },
        "0113": {
            0: "正常",
            1: "浸水",
        },
    }

    def __init__(self):
        self.special_control_list = [
            i for i in self.DATA_MAP.keys() if i != "0020"
        ]
        self.power_switch_list = [
            f"{i:04X}" for i in range(0x20, 0x49) if i % 2 == 0
        ]
        self.power_value_list = [
            f"{i:04X}" for i in range(0x20, 0x4A) if i % 2 == 1
        ]
        self.amplitude_parm_list = [
            f"{i:04X}" for i in range(0x4A, 0x55)
        ]

        self.temp_control_list = [
            "0016", "0017", "0018", "0019", "010D", "0110",
        ]
        self.amplitude_control_list = [
            "0104", "0105", "0106",
        ]
        self.special_voltage_list = [
            "001B", "001C",
        ]
        self.multi_mod_list = [
            "0016",
        ]
        self.long_data_control_list = ["0002", "0009", "0012"]
        self.no_transformed_control_list = ["0000", "0011", "001D", "0055", "0056", "0057",
                                            "001E"] + self.amplitude_parm_list
        self.INVERTED_DATA_MAP = self.invert_inner_dicts()

    def process_data(self, response_data):

        for address, value in response_data.items():
            if address in self.special_control_list:
                response_data[address] = self.DATA_MAP[address].get(value)
            elif address in self.temp_control_list:
                if value >= 32768:
                    value = (value - 65536)
                response_data[address] = value / 10
            elif address in self.amplitude_control_list:
                if value >= 32768:
                    value = (value - 65536)
                response_data[address] = value / 100
            elif address in self.special_voltage_list:
                response_data[address] = value / 1000
            elif address in self.power_switch_list:
                response_data[address] = self.DATA_MAP['0020'].get(value)
            elif address == "0006":
                hex_value = hex(value)
                str_hex_value = hex_value[2:].zfill(4)
                response_data[address] = (f"APP{int(str_hex_value[0], 16)} "
                                          f"V{int(str_hex_value[1], 16)}."
                                          f"{int(str_hex_value[2:], 16)}")
            elif address == "0007":
                str_value = str(value)
                response_data[address] = f"F.{str_value.zfill(3)}"
            elif address == "0008":
                response_data[address] = hex(value)
            elif address == "001F":
                response_data[address] = self.process_weekday_data(value)

    def process_weekday_data(self, input_value):
        # 把十进制数字转换为二进制
        binary_value = bin(input_value)[2:].zfill(7)
        output_value = str(binary_value)[::-1]
        return output_value

    def bin_to_hex(self, value):
        value_dec = int(value, 2)
        value_hex = format(value_dec, '04x')
        value_h = int(value_hex[0:2], 16)
        value_l = int(value_hex[2:], 16)
        return value_h, value_l

    def long_write_data_process(self, data):
        function_code = 0x10
        address, value = data[2], data[-1]
        address_h = int(address[0:2], 16)
        address_l = int(address[2:4], 16)
        regis_count_h, regis_count_l = 0x00, 0x02
        byte_count = 0x04
        if address == "0009":
            date_string = value
            date_format = '%Y/%m/%d %H:%M:%S'
            set_date_time = datetime.strptime(date_string, date_format)
            base_time = datetime(2001, 1, 1, 0, 0, 0)
            time_difference = set_date_time - base_time
            value = time_difference.total_seconds()
        value_hex = format(int(value), '08x')
        data_1_h, data_1_l = int(value_hex[0:2], 16), int(value_hex[2:4], 16)
        data_2_h, data_2_l = int(value_hex[4:6], 16), int(value_hex[6:], 16)
        return function_code, address_h, address_l, regis_count_h, regis_count_l, byte_count, data_1_h, data_1_l, data_2_h, data_2_l

    def multi_write_data_process(self, data):
        function_code = 0x10
        address, values = data[2], data[-1]
        address_h = int(address[0:2], 16)
        address_l = int(address[2:4], 16)
        regis_count_l = len(values)
        regis_count_h = 0x00
        if regis_count_l > 255:
            regis_count_l = regis_count_l % 256
            regis_count_h = 1

        data_pairs = []
        for value in values:
            value_hex = format(value, '04x')
            value_h = int(value_hex[0:2], 16)
            value_l = int(value_hex[2:], 16)
            data_pairs.append((value_h, value_l))

        return function_code, address_h, address_l, regis_count_h, regis_count_l, data_pairs


    def write_data_process(self, data):
        function_code = 0x06
        address, value = data[2], data[-1]
        address_h = int(address[0:2], 16)
        address_l = int(address[2:4], 16)
        if address in self.special_control_list:
            value_h = 0x00
            value_l = self.INVERTED_DATA_MAP[address].get(value)
        elif address in self.power_switch_list:
            value_h = 0x00
            value_l = self.INVERTED_DATA_MAP['0020'].get(value)
        elif address in self.temp_control_list:
            value_dec = int(float(value) % 100) * 10
            value_hex = format(value_dec, '04x')
            value_h = int(value_hex[0:2], 16)
            value_l = int(value_hex[2:], 16)
        elif address in self.amplitude_control_list:
            value_dec = int(float(value) % 100) * 100
            value_hex = format(value_dec, '04x')
            value_h = int(value_hex[0:2], 16)
            value_l = int(value_hex[2:], 16)
        elif address in self.special_voltage_list:
            value_dec = int(float(value) % 1000) * 1000
            value_hex = format(value_dec, '04x')
            value_h = int(value_hex[0:2], 16)
            value_l = int(value_hex[2:], 16)
        elif address in self.power_value_list:
            hours, minutes, seconds = map(int, value.split(':'))
            total_seconds = hours * 3600 + minutes * 60 + seconds
            value_hex = format(total_seconds, '04x')
            value_h = int(value_hex[0:2], 16)
            value_l = int(value_hex[2:], 16)
        elif address in self.no_transformed_control_list:
            value = format(int(value), '04x')
            value_h = int(value[0:2], 16)
            value_l = int(value[2:4], 16)
        elif address == "00FF":
            value_h = 0x00
            value_l = 0x01 if value == "True" else 0x00
        elif address == "001F" and len(value) == 7:
            value_h, value_l = self.bin_to_hex(value)
        elif address == "0010":
            value_h, value_l = 0x00, 0x00
        else:
            return
        return function_code, address_h, address_l, value_h, value_l

    def invert_inner_dicts(self, ):
        # 遍历第一层字典的所有键
        data_map = copy.deepcopy(self.DATA_MAP)
        for key in data_map:
            # 获取当前键对应的第二层字典
            inner_dict = data_map[key]

            # 创建一个新的字典来存储对调后的键值对
            inverted_dict = {}

            # 遍历第二层字典
            for inner_key, inner_value in inner_dict.items():
                # 将键转换为字符串，并作为新字典的键
                inverted_dict[str(inner_value)] = inner_key

            # 更新当前键下的字典
            data_map[key] = inverted_dict

        return data_map


# 示例数据


if __name__ == '__main__':
    data_process = DataProcess()
    # print(data_process.power_value_list)
    print(data_process.no_transformed_control_list)
    test_input_data = {'0000': 1, '0001': 8, '0002': 0, '0003': 1376256000, '0005': 0, '0006': 4352, '0007': 4,
                       '0008': 64, '0009': 599610935, '000B': 0, '000C': 0, '000D': 0, '000E': 0, '000F': 0, }
    test_input_data2 = ('1', '配网低功耗', '0021', '序号1时刻时间值', '00:00:00', '00:00:02')
    # print(data_process.long_write_data_process(test_input_data2))
    print(data_process.write_data_process(test_input_data2))
    # data_process.process_data(test_input_data)
    # print(test_input_data)
